package com.erp.erp_ui.bill_declare;

import com.erp.enums.ModuleTypeEnum;
import com.erp.erp_entitys.User.UserEntity;
import com.erp.erp_entitys.bill_declare.*;
import com.erp.erp_entitys.business.entity.CarryDetailEntity;
import com.erp.erp_entitys.business.entity.CarryDetailProductEntity;
import com.erp.erp_entitys.business.entity.CarryDetailProductPartsEntity;
import com.erp.erp_servers.Company.ICompanyService;
import com.erp.erp_servers.Drawback.DrawbackService;
import com.erp.erp_entitys.warehouse.entity.AnnexEntity;
import com.erp.erp_servers.Ftp.IFtpService;
import com.erp.erp_servers.bill_declare.BillDeclareInfoService;
import com.erp.erp_servers.business.ICarryDetailProductPartsService;
import com.erp.erp_servers.business.ICarryDetailProductService;
import com.erp.erp_servers.business.ICarryDetailService;
import com.erp.erp_servers.warehouse.IAnnexService;
import com.erp.erp_servers.warehouse.ITempAnnexService;
import com.erp.erp_ui.BillExchangeInfo.ChangeUnit;
import com.erp.erp_ui.base.Base;
import com.erp.erp_ui.warehouse.enums.DataIsValidEnum;
import com.erp.erp_ui.warehouse.req.AnnexReq;
import com.erp.erp_ui.warehouse.vo.AnnexVo;
import com.erp.utils.DateUtils;
import com.erp.utils.R;
import com.erp.utils.ResultStatusEnum;
import com.erp.vo.SelectVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.math.BigDecimal;
import java.util.*;

/**
 * 报关主信息表(BillDeclareInfo)表控制层
 *
 * @author makejava
 * @since 2021-01-08 17:44:10
 */
@Controller
@RequestMapping("billDeclare")
public class BillDeclareInfoController extends Base {
    /**
     * 服务对象
     */
    @Autowired
    private BillDeclareInfoService billDeclareInfoService;
    @Autowired
    private   ICarryDetailService carryService;
    @Autowired
    private   ICarryDetailProductService produceService;
    @Autowired
    private  ICarryDetailProductPartsService partsService;
    @Autowired
    private DrawbackService drawbackService;
    @Autowired
    private  IFtpService ftpService;
    @Autowired
    private  ITempAnnexService tempAnnexService;
    @Autowired
    private  ICompanyService companyService;
    /**
     * 附件接口
     */
    @Autowired
    private  IAnnexService annexService;



    /*
     * 分页查询所有的报关表
     * */
    @GetMapping(value = "getUser")
    @ResponseBody
    public R<UserEntity> selectAllBill() {
        UserEntity user = (UserEntity) this.getBean("user");
        return  R.build(user);
    }
    /*
    /*
   * 分页查询所有的报关表
   * */
    @GetMapping(value = "selectAllBillByPage")
    @ResponseBody
    public R<List<BillDeclareInfo>> selectAllBill(InfoSearch search) {
        List<BillDeclareInfo> infos = billDeclareInfoService.selectAllInfobySearch(search);
        return  R.build(infos);
    }
    /*
     * 分页查询出运产品
     * */
    @GetMapping(value = "selectCarryProductByPage")
    @ResponseBody
    public R<List<CarryDetailProductEntity>> selectCarryProductByPage(Integer id) {
        List<CarryDetailProductEntity> infos = billDeclareInfoService.queryCarryProductByCarryId(id);
        List<CarryDetailProductEntity> products=new ArrayList<>();
        for(CarryDetailProductEntity pro :infos){
            BillDeclareProductInfo info = new BillDeclareProductInfo(pro);
            BigDecimal bigDecimal = billDeclareInfoService.selectLastAmount(info);
            BigDecimal last=info.getGoodsNum().subtract(bigDecimal);
            if(last.compareTo(new BigDecimal(0))>0){
                pro.setLastAmount(last);
                pro.setCostSubtotal(pro.getCostUnitPrice().multiply(last));
                pro.setMoneySubtotal(pro.getFcUnitPrice().multiply(last));
                products.add(pro);
            }
        }
        return  R.build(products);
    }
    /*
     * 分页查询出运明细
     * */
    @GetMapping(value = "selectAllCarryByPage")
    @ResponseBody
    public R<List<CarryDetailEntity>> selectAllCarryByPage(carryInfoSearch search) {
        UserEntity user = (UserEntity) this.getBean("user");
        search = BillUnit.getSearch(search);
        List<CarryDetailEntity> infos =new ArrayList<>();
        try {
            if(search.getNumberremaining()==null&&search.getMdate()==null&&search.getInvoiceno()==null&&search.getEndmdate()==null&&search.getCustomername()==null&&search.getCustomercontractno()==null&&search.getContractno()==null){
                search.setIsNull(0);
            }else{
                search.setIsNull(1);
            }
             infos = billDeclareInfoService.queryCarryBySearchBillDeclare(search);
        }catch (Exception e ){

        }
        for(CarryDetailEntity ca:infos){
            ca.setOperator(user.getName());
        }
        return  R.build(infos);
    }
    /*
    * 查询所有的签约公司
    * */
    @GetMapping(value = "selectAllcompanyAndpeople")
    @ResponseBody
    public R<Map<String, List>> selectAllcompanyAndpeople(Integer Type) {
        //查询所有的签约公司
        List<SelectVo> list = companyService.getAllList();
        Map<String,List> map=new HashMap<>();
        map.put("companyName",list);
        return R.build(map);

    }
    /*
     * 导入出运后生成报关
     * */
    @GetMapping(value = "reBackBill")
    @ResponseBody
    public R<Integer> reBackBill(@RequestBody AnswerCarry ans) {
        List<Integer> carryId = ans.getCarryId();
        List<Integer> productId = ans.getCarrtProductId();
        List<Integer> partId = ans.getCarrtPartId();
        CarryDetailEntity carry = carryService.queryById(carryId.get(0));
        //生成info
        BillDeclareInfo info=new BillDeclareInfo(carry);
        billDeclareInfoService.insertInfo(info);
        Integer infoId = info.getDeclareId();
        //生成produce
        for(Integer id:productId){
            CarryDetailProductEntity product = produceService.queryById(id);
            BillDeclareProductInfo billPro=new BillDeclareProductInfo(product);
            billPro.setDeclareId(infoId);
            billDeclareInfoService.insertProductInfo(billPro);
        }
        //生成配件
        for(Integer id:partId){
            CarryDetailProductPartsEntity part = partsService.queryById(id);
            BillDeclareProductInfo billPro=new BillDeclareProductInfo(part);
            billPro.setDeclareId(infoId);
            billDeclareInfoService.insertProductInfo(billPro);
        }
        return  R.build(infoId);
    }
    /*
     * 根据id查询报关表信息
     * */
    @GetMapping(value = "selectBillById")
    @ResponseBody
    public R<BillDeclareInfo> reBackBill(Integer billId) {
        BillDeclareInfo info = billDeclareInfoService.queryInfoById(billId);
        return R.build(info);
    }
    /*
    * 根据id删除报关表和产品标配
    * deleteBillById
    * */
    @GetMapping(value = "deleteBillById")
    @ResponseBody
    public R<String> deleteBillById(Integer billId) {
        String succ="success";
        try{
            billDeclareInfoService.deleteInfoById(billId);
            List<BillDeclareProductInfo> infos = billDeclareInfoService.queryAllProductInfoByBillId(billId);
            for(BillDeclareProductInfo p:infos){
                billDeclareInfoService.deleteProductInfoById(p.getDeclareProductId());
            }
            //根据报关主表id删除退税表中的信息
            drawbackService.deleteDrawbackByBillDeclareInfoId(billId);

        }catch (Exception e){
            succ="wrong";
        }
        return R.build(succ);
    }

    /*
    * 修改报关表状态
    *(1.草稿箱 2.待批箱 3.已批箱 4.完成箱 5.垃圾箱)
    * */
    @GetMapping(value = "changeBillById")
    @ResponseBody
    public R<String> changeBillById(Integer billId, Integer statues) {
        String succ="success";
        try{
            BillDeclareInfo info = billDeclareInfoService.queryInfoById(billId);
            info.setStatus(statues);
            billDeclareInfoService.updateInfo(info);
        }catch (Exception e){
            succ="wrong";
        }
        return R.build(succ);
    }
    /*
     * 根据id查询报关表信息
     * */
    @GetMapping(value = "selectProductAndPartsById")
    @ResponseBody
    public R<List<BillDeclareProductInfo>> selectProductAndPartsById(Integer billId) {
        List<BillDeclareProductInfo> infos = billDeclareInfoService.queryAllProductInfoByBillId(billId);
        return R.build(infos);
    }
/*
* 查询最大可报关数量
* */
@GetMapping(value = "selectLastAmontById")
@ResponseBody
public R<BigDecimal> selectLastAmontById(@RequestParam(value = "proid") Integer proid) {
        BillDeclareProductInfo info = billDeclareInfoService.queryProductInfoById(proid);
        BigDecimal bigDecimal = billDeclareInfoService.selectLastAmount(info);
        BigDecimal lastDecimal=info.getGoodsNum().subtract(bigDecimal);
        return R.build(lastDecimal);
}

    /*
    * 将出运产品和出运配件转换为报关产品
    * */
    @PostMapping(value="changeProductsAndParts")
    @ResponseBody
    public R<List<BillDeclareProductInfo>> changeProductsAndParts(@RequestBody List<CarryDetailProductEntity> pro){
        List<BillDeclareProductInfo> billPro=new ArrayList<>();
        if(pro.size()>0){
            for(CarryDetailProductEntity p:pro){
                BillDeclareProductInfo productInfo = new BillDeclareProductInfo(p);
                BigDecimal bigDecimal = billDeclareInfoService.selectLastAmount(productInfo);
                BigDecimal last=productInfo.getGoodsNum().subtract(bigDecimal);
                if(last.compareTo(new BigDecimal(0))>0){
                    productInfo.setLastAmount(last);
                    p.setCostSubtotal(p.getCostUnitPrice().multiply(last));
                    p.setMoneySubtotal(p.getFcUnitPrice().multiply(last));
                    billPro.add(productInfo);
                }
                List<CarryDetailProductPartsEntity> parts = billDeclareInfoService.selectPartsByProduct(p);
                if(parts.size()>0){
                    for(CarryDetailProductPartsEntity pa:parts){
                        BillDeclareProductInfo billDeclareProductInfo = new BillDeclareProductInfo(pa);
                        billDeclareProductInfo.setCarryProductsId(p.getId());
                        BigDecimal bigDecimal1 = billDeclareInfoService.selectLastAmount(billDeclareProductInfo);
                        BigDecimal last1=billDeclareProductInfo.getGoodsNum().subtract(bigDecimal);
                        if(last1.compareTo(new BigDecimal(0))>0){
                            billDeclareProductInfo.setLastAmount(last1);
                            pa.setCostSubtotal(pa.getCostUnitPrice().multiply(last1));
                            billPro.add(billDeclareProductInfo);
                        }
                    }
                }
            }
        }
        return R.build(billPro);
    }
    /*
     * 新建报关表
     * */
    @PostMapping(value = "addBillInfo")
    @ResponseBody
    public R<Integer> addBillInfo(@RequestBody BillDeclareInfo info, @RequestParam(value = "id")Integer id) {
        if(id==-1){
            info.setStatus(1);
            billDeclareInfoService.insertInfo(info);
        }else{
            info.setDeclareId(id);
            info.setEditTime(new Date());
            billDeclareInfoService.updateInfo(info);
        }
        return R.build(info.getDeclareId());
    }

    /*
     * 新建报关产品表
     * */
    @PostMapping(value = "addBillProductInfo")
    @ResponseBody
    public R<String> addBillProductInfo(@RequestBody List<BillDeclareProductInfo> infos, @RequestParam(value = "billid") Integer billid, @RequestParam(value = "id") Integer id) {
        String succ="success";
        if(id==-1){
           List<Integer> success=new ArrayList<>();
           try{
               for(BillDeclareProductInfo pro:infos){
                   pro.setDeclareId(billid);
                   billDeclareInfoService.insertProductInfo(pro);
                   success.add(pro.getDeclareProductId());
               }
           }catch (Exception e ){
               succ="wrong";
           }
           if(succ.equals("wrong")){
               for(Integer i:success){
                   billDeclareInfoService.deleteInfoById(billid);
                   billDeclareInfoService.deleteProductInfoById(i);

               }
           }
       }else{
           try{
               List<BillDeclareProductInfo> delete=new ArrayList<>();
               List<BillDeclareProductInfo> change=new ArrayList<>();
               List<BillDeclareProductInfo> add=new ArrayList<>();
               List<BillDeclareProductInfo> billDeclareProductInfos = billDeclareInfoService.queryAllProductInfoByBillId(billid);
               for(BillDeclareProductInfo pro:billDeclareProductInfos){//数据库查询的结果
                 int i=0;//i=1时相同
                   for(BillDeclareProductInfo old:infos){//新提交的结果
                       if(pro.getDeclareProductId().equals(old.getDeclareProductId())){//如果新旧的相等，则修改
                           change.add(old);
                           i=1;
                       }
                   }
                   if(i==0){
                       delete.add(pro);
                   }
               }
               for(BillDeclareProductInfo old:infos){
                   int i=0;
                   for(BillDeclareProductInfo pro:billDeclareProductInfos){//数据库查询的结果
                       if(pro.getDeclareProductId().equals(old.getDeclareProductId())){//如果提交的有，数据库没有，则新增。如果提交的没有，数据库有，则删除
                           i=1;
                       }
                        }
                   if(i==0){
                       add.add(old);
                   }
               }
               if(change.size()>0){
                   for(BillDeclareProductInfo c:change){
                       billDeclareInfoService.updateProductInfo(c);
                   }
               }
               if(add.size()>0){
                   for(BillDeclareProductInfo c:add){
                       c.setDeclareId(billid);
                       billDeclareInfoService.insertProductInfo(c);
                   }
               }
               if(delete.size()>0){
                   for(BillDeclareProductInfo c:delete){
                       billDeclareInfoService.deleteProductInfoById(c.getDeclareProductId());
                   }
               }
           }catch (Exception e ){
               succ="wrong";
           }
       }

        return R.build(succ);
    }

    /**
     * FTP文件上传
     * @param request
     * @return
     */
    @RequestMapping(value = "uploadFile" ,method = RequestMethod.POST, consumes = "multipart/*")
    @ResponseBody
    public R transferFileUpload(MultipartHttpServletRequest request){
        try {
            String ftpPath = getFtpPath();
            UserEntity user = (UserEntity)this.getBean("user");
            String operator = user.getName();
            String operatorNo = user.getCode();
            List<AnnexVo> annexVos =BillUnit.transferFileUpload(tempAnnexService,ftpService,request, ftpPath, operator, operatorNo);
            return R.build(annexVos);
        }catch (Exception e){
            return R.buildError(ResultStatusEnum.UPLOAD_FILE_ERROR);
        }
    }
    /**
     * 新增、修改
     * @param req 新增、修改入参
     * @return 新增、修改结果
     */
    @PostMapping("/add")
    @ResponseBody
    public R add(@RequestBody List<AnnexReq> req, @RequestParam(value = "id") Integer id, @RequestParam(value = "type") Integer type){//type==-1  新增 type!=-1 修改
        try {
            UserEntity user = (UserEntity)this.getBean("user");
            String name = user.getName();
            String code = user.getCode();
            if(type==-1){
                return BillUnit.add(tempAnnexService,annexService,req,name, id,code);
            }else{
                annexService.deleteAnnex(ModuleTypeEnum.BILLDECLARE_FILE.getId(),id);
                return BillUnit.add(tempAnnexService,annexService,req,name, id,code);
            }

        }catch (Exception e){
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
    }
    /**
     * ftp路径，/upload/部门编码/员工编码
     * @return
     */
    private String getFtpPath(){
        try {
            UserEntity user = (UserEntity)this.getBean("user");
            String code = user.getCode();
            String departmentCode = user.getDepartmentCode();
            return "/data0/AllPath/upload/"+departmentCode+"/"+code;
        }catch (Exception e){
            e.printStackTrace();
            return "/data0/AllPath/upload";
        }

    }

    /*
    * 根据表id查询附件
    * */
    //获取对应所有附件
    @GetMapping("/selectBillFile")
    @ResponseBody
    public R<List<AnnexVo>> add(Integer type,Integer parentId){
        Integer moduleId=-1;
        if(type==0){//查询出运
            moduleId=ModuleTypeEnum.BUSINESS_CARRY_DETAIL.getId();
        }else if(type==1){//查询报关
            moduleId=ModuleTypeEnum.BILLDECLARE_FILE.getId();
        }else if(type==2){//查询结汇
            moduleId=ModuleTypeEnum.BILLCHANGE_FILE.getId();
        }else if(type==3){//查询清关
            moduleId=ModuleTypeEnum.BILLCLEAR_FILE.getId();
        }
       AnnexEntity annex = new AnnexEntity();
       annex.setModuleId(moduleId);
       annex.setParentId(parentId);
       annex.setValid(DataIsValidEnum.VALID.getId());
       List<AnnexEntity> annexList = annexService.queryAll(annex);
        List<AnnexVo>  anvoList=new ArrayList<>();
       for(AnnexEntity a:annexList){
           AnnexVo v=new AnnexVo();
           v.setId(a.getId());
           v.setUploadTime(DateUtils.format(a.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
           v.setFileName(a.getFileName());
           v.setFilePath(a.getFilePath());
           anvoList.add(v);
       }
       return R.build(anvoList);
    }
    /*
     * 查询公司的logo和img
     * */
    //获取对应所有附件
    @GetMapping("/selectLogo")
    @ResponseBody
    public R<logo> selectLogo(Integer declare_id){
        logo logo=new logo();
        try {
            com.erp.erp_entitys.bill_declare.logo logo1 = billDeclareInfoService.selectLogo(declare_id);
            if(logo1.getChinaLogo()!=null){
                ftpService.ftpUpload(logo1.getChinaLogo());
            }
            if(logo1.getEnginshLogo()!=null){
                ftpService.ftpUpload(logo1.getEnginshLogo());
            }
            if(logo1.getSimg()!=null){
                ftpService.ftpUpload(logo1.getSimg());
            }

        }catch (Exception e){
            System.out.println(e);
        }
        return R.build(logo);
    }
    /*
     * 验证单号是否唯一
     * */
    @GetMapping("/checkBillNo")
    @ResponseBody
    public R<String> checkBillNo(String  invoicenumber,Integer id){
        String re="success";
        try {
           List<BillDeclareInfo> bills= billDeclareInfoService.checkBillNo(invoicenumber);
            BillDeclareInfo billDeclareInfo = billDeclareInfoService.queryInfoById(id);
            String no = "";
            if(id!=-1){
              no=  billDeclareInfo.getInvoiceNo();//原有报关单号
            }
            if(bills.size()>0){
               re="wrong";
           }
            if(invoicenumber.equals(no)){
                re="success";
            }
        }catch (Exception e){
           re="wrong";
        }
        return R.build(re);
    }

    /*
     * 报关统计查询
     * */
    @GetMapping("/selectStatByPage")
    @ResponseBody
    public R selectStatByPage(statSearch search){
        if(search.getStatus()==null&&search.getSalesman_code()==null&&search.getOp_code()==null&&search.getInvoiceStar()==null&&search.getInvoiceEnd()==null
                &&search.getCompany_code()==null&&search.getCarryStar()==null&&search.getCarryEnd()==null&&search.getBill()==null&&search.getAtdEnd()==null&&search.getAtdStar()==null
        &&search.getEtaStar()==null&&search.getEtaEnd()==null&&search.getEtdStar()==null&&search.getEtdEnd()==null&&search.getStockStar()==null&&search.getStockEnd()==null
        &&search.getDeptSalesmanCode()==null&& search.getDeptOperationCode()==null &&search.getBillCustmsDeclareNo()==null){
            search.setStatus(-1);
        }
        statSearch search1 = ChangeUnit.getSearch(search);
        List<BillDeclareInfo> infos=billDeclareInfoService.selectStatSearch(search1);
        return R.build(infos);
    }


    /**
     *
     * 判断该用户是否拥有 报关主信息字段及产品字段显示(BGCPZDXS001) 角色
     */
    @RequestMapping("isContainsRole")
    @ResponseBody
    public R isContainsRole(){
        try {
            UserEntity user = (UserEntity) this.getBean("user");
            if (user.getRoles().contains("BGCPZDXS001")){
                return R.build(true);
            }else {
                return R.build(false);
            }
        } catch (Exception e) {
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }

    }

}